function defaultToString(item) {
    if (item === null) {
        return 'null';
    } else if (item === undefined) {
        return 'UNDIFINED';
    } else if (typeof item === 'string' || item instanceof String) {
        return `${item}`
    } else {
        return item.toString()
    }

}

class ValuePair {
    constructor(key, value) {
        this.key = key;
        this.value = value;
    };
    toString() {
        return `[#${this.key}:${thsi.value}`
    }
}

class HashMap {
    constructor(toStrFn = defaultToString) {
        this.table = {};
        this.toStrFn = toStrFn;
    };
    loseloseHashCode(key) {
        if (typeof key === 'number') {
            return key
        };
        const tableKey = this.toStrFn(key);
        let hash = 0;
        for (let i = 0; i < tableKey.length; i++) {
            hash += tableKey.charCodeAt(i);
        };
        return hash % 37;
    };
    hashCode(key) {
        return this.loseloseHashCode(key)
    };


    put(key, value) {
        if (key != null && value != null) {
            const position = this.hashCode(key);
            this.table[position] = new ValuePair(key, value);
            return true;
        } else {
            return false;
        }
    }

    get(key) {
        const ValuePair = this.table[this.hashCode(key)];
        return ValuePair = null ? undefined : ValuePair.value;
    }

    remove(key) {
        const hash = this.hashCode(key);
        const ValuePair = this.table[hash];
        if (ValuePair != null) {
            delete this.table[hash];
            return true
        } else {
            return false
        }
    }

    // 新哈希化函数
    djb2HashCode(key) {
        const tableKey = this.toStrFn(key);
        let hash = 5381;
        for (let i = 0; i < tableKey.length; i++) {
            hash = (hash * 33) + tableKey.charCodeAt(i);
        }
        return hash % 1013;
    }
}